package com.junchenrobot.mes.core;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.junchenrobot.mes.dao.DeviceDao;
import com.junchenrobot.mes.dao.WinderTaskRunDao;
import com.junchenrobot.mes.dao.WinderTaskSpareDao;
import com.junchenrobot.mes.dao.WinderTimeDao;
import com.junchenrobot.mes.domain.Device;
import com.junchenrobot.mes.domain.WinderTask;
import com.junchenrobot.mes.domain.WinderTaskRun;
import com.junchenrobot.mes.domain.WinderTaskSpare;
import com.junchenrobot.mes.listener.source.WinderTaskRedisRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

@Slf4j
@Component
public class TaskStored {

    @Autowired
    WinderTaskRedisRepository winderTaskRedisRepository;
    @Autowired
    WinderTaskSpareDao winderTaskSpareDao;
    @Autowired
    WinderTaskRunDao winderTaskrunDao;
    @Autowired
    DeviceDao deviceDao;
    @Autowired
    WinderTimeDao winderTimeDao;

    private final List<WinderTask> winderList = new LinkedList<>();

    /**
     * 任务索引
     */
    private final List<Long> taskIndex = new CopyOnWriteArrayList<>();

    /**
     * 获取任务
     *
     * @return {@link WinderTask}
     */
    public WinderTaskSpare getFirst() {

        //读取备选任务表中的所有任务
        List<WinderTaskSpare> winderTaskSpareList = winderTaskSpareDao.listUnFinishedTask();
        log.info("winderTaskSpareList.size{}:", winderTaskSpareList.size());
        if (CollectionUtils.isEmpty(winderTaskSpareList)) {
            log.info("任务池中无任务");
            return null;
        }
        return getWinderTask(winderTaskSpareList);
    }


    /**
     * 计算出最优分配的任务(适用于空闲车的左杆)
     *
     * @return WinderTask
     */
    public WinderTaskSpare getWinderTask(List<WinderTaskSpare> list) {
        //查询1线所有任务里报警时间比现在时间晚10分钟的时间小的还没有接到的任务
        //十分钟后的时间
        LocalDateTime time = LocalDateTime.now().plusMinutes(10);
        List<WinderTaskSpare> winderTaskSpareList = list.stream()
                .filter(winderTaskSpare -> winderTaskSpare.getTaskWinderLine() == 1)
                .filter(winderTaskSpare ->winderTaskSpare.getTaskWarnTime().isBefore(time))
                .collect(Collectors.toList());
        log.info("1线报警时间比现在晚10分钟的时间小的还没有接到的任务列表{}",winderTaskSpareList.size());
        if (winderTaskSpareList.size()>0){
            winderTaskSpareList.sort((x, y) -> Long.compare(x.getTaskWarnTime().toEpochSecond(ZoneOffset.of("+8")), y.getTaskWarnTime().toEpochSecond(ZoneOffset.of("+8"))));
            return winderTaskSpareList.get(0);
        }

        List<WinderTaskSpare> winderTaskSpareList1 = list.stream()
                .filter(winderTaskSpare -> winderTaskSpare.getTaskWinderLine() == 2)
                .filter(winderTaskSpare ->winderTaskSpare.getTaskWarnTime().isBefore(time))
                .collect(Collectors.toList());
        log.info("2线报警时间比现在晚10分钟的时间小的还没有接到的任务列表{}",winderTaskSpareList1.size());
        if (winderTaskSpareList1.size()>0){
            winderTaskSpareList1.sort((x, y) -> Long.compare(x.getTaskWarnTime().toEpochSecond(ZoneOffset.of("+8")), y.getTaskWarnTime().toEpochSecond(ZoneOffset.of("+8"))));
            return winderTaskSpareList1.get(0);
        }
        winderTaskSpareList.addAll(winderTaskSpareList1);

        Integer TaskWinderLine = 1;
        //获取1号线所有任务
        List<WinderTaskSpare> device = findDevice(TaskWinderLine, list);
        log.info("==1====");
        if (device.size() > 0) {//1号线是否有任务
            log.info("=2=====");
            ////按报警时间排序
            device.sort((x, y) -> Long.compare(x.getTaskWarnTime().toEpochSecond(ZoneOffset.of("+8")), y.getTaskWarnTime().toEpochSecond(ZoneOffset.of("+8"))));

//            //按卷绕机号升序排序
//            device.sort((x, y) -> Double.compare(x.getTaskWinderSpinningCode(), y.getTaskWinderSpinningCode()));
//            log.info("==3====");
//            //倒序输出(1号线 48-1)
//            Collections.reverse(device);
//            log.info("==4====");
//            //查询正在运行的设备任务
//            List<WinderTaskRun> winderTaskRuns = winderTaskrunDao.listUnFinishedTask();
//            log.info("==5====");
//            //拿到run表里1号线的正在做的小车任务
//            winderTaskRuns = winderTaskRuns.stream()
//                    .filter(WinderTaskRun -> WinderTaskRun.getTaskWinderLine() == 1)
//                    .collect(Collectors.toList());
////            winderTaskRuns.sort((x, y) -> Double.compare(x.getTaskWinderSpinningCode(), y.getTaskWinderSpinningCode()));
//            log.info("==6====");
//            log.info("{}", winderTaskRuns.size());
//
//            if (winderTaskRuns.size() > 0) {  //判断run表里1号线的正在做的小车任务是否为空
//                log.info("==7====");
//                //判断有车在接任务,那么空闲车就接1号线的时间最短的任务
//                //按报警时间排序
//                device.sort((x, y) -> Long.compare(x.getTaskWarnTime().toEpochSecond(ZoneOffset.of("+8")), y.getTaskWarnTime().toEpochSecond(ZoneOffset.of("+8"))));
//                log.info("{}", device.size());
//                log.info("==9====");
//            }
            //为空则按最远卷绕机号接任务
        } else {
            TaskWinderLine = 2;
            //获取2号线所有任务
            device = findDevice(TaskWinderLine, list);
            log.info("==10====");
            if (device.size() > 0) {
                log.info("==11====");
                //2号线任务排序(2号线  1-48)
                device.sort((x, y) -> Double.compare(x.getTaskWinderSpinningCode(), y.getTaskWinderSpinningCode()));
            }
            log.info("==111====");
        }
        WinderTaskSpare winderTask1 = device.get(0);
        log.info("==12====");
        log.info("{}", winderTask1);
        return winderTask1;
    }

    /**
     * 查询某线线所有任务
     * @param TaskWinderLine 线号
     * @param list 所有备用任务
     * @return 该线所有任务
     */
    public List<WinderTaskSpare> findDevice(Integer TaskWinderLine, List<WinderTaskSpare> list) {
        //过滤任务,只剩下卷绕机线号为1线并且卷绕机机号大于0 的任务
        List<WinderTaskSpare> collect = list.stream()
                .filter(WinderTaskSpare -> WinderTaskSpare.getTaskWinderLine().equals(TaskWinderLine) )
                .collect(Collectors.toList());
        return collect;

    }

    /**
     * 络筒机添加任务
     *
     * @param
     */

    public void addWinderTask(List<WinderTaskSpare> winderTaskSpareList1) {

        winderTaskSpareList1.forEach(v -> {
            taskIndex.add(v.getTaskWinderId());
        });
        //新的备用列表按时间重新排序
        winderTaskSpareList1.sort((x, y) -> Long.compare(x.getTaskWarnTime().toEpochSecond(ZoneOffset.of("+8")), y.getTaskWarnTime().toEpochSecond(ZoneOffset.of("+8"))));
        List<WinderTask> winderTaskList = new LinkedList<>();
        BeanUtils.copyProperties(winderTaskSpareList1, winderTaskList);
        winderList.addAll(winderTaskList);
        //清空旧的备用表
        winderTaskSpareDao.deleteAll();
        //将新的备用列表加入到数据库中
        log.info("更新后添加备用列表的数量{}", winderTaskSpareList1.size());
        for (WinderTaskSpare winderTaskSpare : winderTaskSpareList1) {
            log.info("/**");
            Long inputTaskTime = winderTimeDao.getInputTaskTime(winderTaskSpare.getTaskWinderLine(), winderTaskSpare.getTaskWinderSpinningCode());
            log.info("inputTaskTime:{}",inputTaskTime);
            winderTaskSpare.setTaskWarnTime(winderTaskSpare.getTaskWarnTime().plusMinutes(inputTaskTime));
            log.info("/**");
            winderTaskSpareDao.insertNewTask(winderTaskSpare);
            log.info("添加进去备用列表任务为:{},{},{}", winderTaskSpare.getTaskWinderId(), winderTaskSpare.getTaskWinderLine(), winderTaskSpare.getTaskWinderSpinningCode());
        }
        log.info("=========备用表更新完成============}");
    }


    public void addWinderTask(WinderTask winderTask) {
        winderList.add(winderTask);
    }


    /**
     * 列表卷绕机任务
     *
     * @return {@link List}<{@link WinderTask}>
     */
    public List<WinderTaskSpare> listWinderTask() {
        List<WinderTaskSpare> winderTaskSpareList = winderTaskSpareDao.listUnFinishedTask();
//        long start = 0;
//        long end = -1;
//        List<WinderTask> list = winderTaskRedisRepository.list(start, end);
//        log.info("从Redis缓存中读取列表中从下标【{}】到下标【{}】的数据，列表的长度：{}",
//                start, end, list.size());
        return winderTaskSpareList;
    }

    /**
     * 查询所有avg小车信息
     * @return 所有avg小车信息
     */
    public List<Device> deviceList(){
        List<Device> deviceList = deviceDao.listDevices();
        return deviceList;
    }

    /**
     * 列出任务索引
     *
     * @return {@link List}<{@link Long}>
     */
    public List<Long> listTaskIndex() {
        return taskIndex;
    }

    public int size() {
        return taskIndex.size();
    }

    /**
     * 备用表中任务数量
     * @return
     */
    public int taskSize() {
        List<WinderTaskSpare> winderTaskSpareList = winderTaskSpareDao.listUnFinishedTask();
        log.info("winderTaskSpareList.size:{}:", winderTaskSpareList.size());
        return winderTaskSpareList.size();
    }

    /**
     * 删除索引
     *
     * @param index 指数
     */
    public void removeIndex(Long index) {
        // 遍历元素
        taskIndex.removeIf(next -> Objects.equals(next, index));
    }


}
